import { getCurrentInstance } from 'vue'
import { infoArticle, collectArticle, starArticle, deleteArticle } from "@/api/article"
import { listComment, saveComment, loadComment, removeComment } from "@/api/comment"
import { attention } from "@/api/user"
import { useStore } from "@/store/main"
import Request from "@/static/network/request"

export default class Methods {
	public id = null
	public info = null
	public loading = false
	public loadEnd = false
	public loadError = false
	public loadingComment = false
	public loadEndComment = false
	public loadErrorComment = false
	public totalComment = 0
	public pageComment = 1
	public limitComment = 10
	public attentionLoading = false
	public collectLoading = false
	public starLoading = false
	public starCommentLoading = false
	public proxy = null
	public commentList = []
	public uploadComment = false
	public uploadReply = false
	public uploadRemove = false
	public addr = ""
	public store = useStore()

	constructor() {
		this.proxy = getCurrentInstance().proxy
		uni.request({
			url: 'http://ip-api.com/json/',
			method: 'POST',
			success: (res : any) : void => {
				this.addr = res.data.city
			}
		})
	}

	public getInfo = (id : number) : Promise<any> => {
		return new Promise((resolve, reject) => {
			if (this.loading) reject()
			this.id = id
			this.loading = true
			this.loadEnd = false
			infoArticle({
				id: this.id
			}).then((res : any) : void => {
				this.info = res.data.info
				this.loadEnd = true
				resolve(this.info)
			}).catch(() : void => {
				this.loadError = true
				reject()
			}).finally(() : void => {
				this.loading = false
			})
		})
	}

	public deleteArt = (id : number) : Promise<any> => {
		return new Promise((resolve, reject) => {
			if (this.loading) reject()
			this.id = id
			this.loading = true
			this.loadEnd = false
			deleteArticle({
				id: this.id
			}).then((res : any) : void => {
				console.log("Res", res);
				this.loadEnd = true
				resolve(this.info)
			}).catch(() : void => {
				this.loadError = true
				reject()
			}).finally(() : void => {
				this.loading = false
			})
		})
	}

	public attentionUser = (info : any) : Promise<number> => {
		if (this.attentionLoading) return
		const status = info.publisher.is_subscribe
		this.attentionLoading = true
		attention({
			user_id: info.publisher.uid,
			type: status === 1 ? 0 : 1
		}).then(() : void => {
			uni.showToast({
				title: this.proxy.$t(status === 1 ? 'index.info.unAttentionSuccess' : 'index.info.attentionSuccess'),
				icon: "none"
			})
			info.publisher.is_subscribe = status === 1 ? 0 : 1
			this.store.setFans(info.publisher.uid, info.publisher.is_subscribe)
			Request.sendSocketMessage({
				data: JSON.stringify({ type: 'info' })
			})
		}).catch(() => {
			uni.showToast({
				title: this.proxy.$t(status === 1 ? 'index.info.unAttentionFail' : 'index.info.attentionFail'),
				icon: "none"
			})
		}).finally(() => {
			this.attentionLoading = false
		})
	}
	public collect = (info : any) : Promise<any> => {
		if (this.collectLoading) return
		this.collectLoading = true
		const status = info.is_collect
		collectArticle({
			id: info.id,
			status: status === 1 ? 0 : 1
		}).then(() : void => {
			uni.showToast({
				title: this.proxy.$t(status === 1 ? 'index.info.unCollectSuccess' : 'index.info.collectSuccess'),
				icon: "none"
			})
			info.collect += status === 1 ? -1 : 1
			info.is_collect = status === 1 ? 0 : 1
			Request.sendSocketMessage({
				data: JSON.stringify({ type: 'info' })
			})
		}).catch(() => {
			uni.showToast({
				title: this.proxy.$t(info.is_collect === 1 ? 'index.info.unCollectFail' : 'index.info.collectFail'),
				icon: "none"
			})
		}).finally(() => {
			this.collectLoading = false
		})
	}

	public star = (info : any, type : number) : Promise<any> => {
		if (this.starLoading) return
		this.starLoading = true
		starArticle({
			id: info.id,
			status: info.is_star === 1 ? 0 : 1,
			type
		}).then(() : void => {
			uni.showToast({
				title: this.proxy.$t(info.is_star === 1 ? 'index.info.unStarSuccess' : 'index.info.starSuccess'),
				icon: "none"
			})
			info.star += info.is_star === 1 ? -1 : 1
			info.is_star = info.is_star === 1 ? 0 : 1
			this.store.setStar(info.id, info.is_star)
			Request.sendSocketMessage({
				data: JSON.stringify({ type: 'info' })
			})
		}).catch(() => {
			uni.showToast({
				title: this.proxy.$t(info.is_star === 1 ? 'index.info.unStarFail' : 'index.info.starFail'),
				icon: "none"
			})
		}).finally(() => {
			this.starLoading = false
		})
	}

	public getComment = (type : number, init ?: boolean) : Promise<any> => {
		return new Promise((resolve, reject) => {
			if (init) {
				this.loadingComment = false
				this.pageComment = 1
				this.totalComment = 0
				this.commentList = []
			}
			if ((this.pageComment - 1) * this.limitComment <= this.totalComment && !this.loadingComment) {
				this.loadErrorComment = false
				this.loadingComment = true
				this.loadEndComment = false
				listComment({
					page: this.pageComment,
					limit: this.limitComment,
					type,
					id: this.id
				}).then((res : any) : void => {
					this.totalComment = res.data.count
					this.commentList = this.commentList.concat(res.data.list)
					this.loadEndComment = true
					this.pageComment += 1
					resolve(this.commentList)
				}).catch(() : void => {
					this.loadErrorComment = true
					reject()
				}).finally(() : void => {
					this.loadingComment = false
				})
			}
		})
	}

	public saveComment = (parent : any, content : string, buid ?: number, cid ?: number, rid ?: number, pid ?: number) : void => {
		if (this.uploadComment) return
		if (!content) {
			uni.showToast({
				title: this.proxy.$t(!cid ? 'index.info.commentNone' : 'index.info.replyNone'),
				icon: "none"
			})
			return
		}
		this.uploadComment = true
		saveComment({
			pid: pid || this.info.id,
			buid,
			cid,
			rid,
			content,
			addr: this.addr
		}).then((res : any) : void => {
			this.uploadComment = false
			uni.showToast({
				title: this.proxy.$t(!cid ? 'index.info.commentSuccess' : 'index.info.replySuccess'),
				icon: "none"
			})
			Request.sendSocketMessage({
				data: JSON.stringify({ type: 'info' })
			})
			if (!cid) {
				res.data.apply = []
				res.data.total_apply = 0
				res.data.userinfo = res.data.from_userinfo
				parent.commentList = parent.commentList.concat([res.data])
			} else {
				if (!parent.ids) parent.ids = []
				parent.ids.push(res.data.id)
				parent.total_apply += 1
				parent.apply = parent.apply.concat([res.data])
			}
		}).catch(() : void => {
			uni.showToast({
				title: this.proxy.$t(!cid ? 'index.info.commentFail' : 'index.info.replyFail'),
				icon: "none"
			})
		}).finally(() : void => {
			this.uploadComment = false
		})
	}

	public loadComment = (info : any) : void => {
		if (!info.page) info.page = 1
		if (info.loading || info.total_apply <= info.apply.length) return
		info.loadError = false
		info.loading = true
		if (info.page === 1) {
			info.ids = info.apply.map((item : any) => item.id)
		}
		loadComment({
			page: info.page,
			limit: 10,
			cid: info.id
		}).then((res : any) : void => {
			info.total_apply = res.data.count
			const list = res.data.list.filter((item : any) => info.ids.findIndex((id : number) => item.id === id) === -1)
			info.apply = info.apply.concat(list)
			info.ids = info.ids.concat(list.map((item : any) => item.id))
			info.page += 1
		}).catch(() : void => {
			info.loadError = true
		}).finally(() : void => {
			info.loading = false
		})
	}

	public removeComment = (info : any) : void => {
		if (this.uploadRemove) return
		this.uploadRemove = true
		removeComment({
			id: info.id
		}).then(() : void => {
			uni.showToast({
				title: this.proxy.$t('index.info.remove.success'),
				icon: "none"
			})
			info.is_delete = 1
		}).catch(() : void => {
			uni.showToast({
				title: this.proxy.$t('index.info.remove.fail'),
				icon: "none"
			})
		}).finally(() : void => {
			this.uploadRemove = false
		})
	}

	public getCommentList = () : any => {
		return this.commentList
	}
}